/*
 * Copyright (c) 2006-2021, RT-Thread Development Team
 *
 * SPDX-License-Identifier: Apache-2.0
 *
 * Change Logs:
 * Date           Author       Notes
 * 2021-11-09     zzzlion       the first version
 */
#include <threadunit/ThreadUnit.h>

ThreadUnit::ThreadUnit()
{
    // TODO 自动生成的构造函数存根
}

ThreadUnit::~ThreadUnit()
{
    // TODO 自动生成的析构函数存根
}

/**
 * @brief Send messages to the message queue in the ThreadUnit->message for other threads or tasks to receive and process
 * （将消息发送到ThreadUnit->message中的消息队列中，供其他线程或任务接收和处理）
 * @param msg_ptr (要发送的消息内容)
 * @return RT_EOK: successful; -RT_EFULL: message queue is full; -RT_ERROR: failed, indicating that the length of the sent message is greater than the maximum length of the messages in the message queue.
 * （RT_EOK 成功；-RT_EFULL 消息队列已满；-RT_ERROR 失败，表示发送的消息长度大于消息队列中消息的最大长度）
 */
int ThreadUnit::recv(msg msg_ptr)
{
    int result = rt_mq_send(&message, (void *)&msg_ptr, sizeof(struct msg));
    return result;
}

/**
 * @brief Dead loop execution: Process messages received from the message queue, and call handleFUn to execute the function corresponding to the message
 * （死循环执行：处理从消息队列中接收到的消息，并调用handleFUn执行消息对应的函数）
 * @param msg
 */
void ThreadUnit::handle(rt_mq_t msg)
{
    while (1)
    {
        struct msg msg_ptr;
        cJSON *json, *json_methodName, *json_params;

        /* 从消息队列中接收消息 */
        if (rt_mq_recv(msg, (void *)&msg_ptr, sizeof(struct msg), RT_WAITING_FOREVER) == RT_EOK)
        {
            // LOG_D("InkSys_thread_entry: recv msg from msg queue, the content:%s\n", msg_ptr.data_ptr);
            json = cJSON_Parse((const char *)msg_ptr.data_ptr);

            if (json != NULL)
            {
                json_methodName = cJSON_GetObjectItem(json, "methodName");
                json_params = cJSON_GetObjectItem(json, "params");

                handleFUn(json_methodName, json_params);

                cJSON_Delete(json);
            }

            rt_free(msg_ptr.data_ptr);
            msg_ptr.data_ptr = RT_NULL;
        }
    }
}

/**
 * @brief Dynamically call the corresponding processing function based on the passed method name
 * （动态地根据传入的方法名调用相应的处理函数）
 * @param methodName （方法名）
 * @param params （传递给方法的参数）
 */
void ThreadUnit::handleFUn(cJSON *methodName, cJSON *params)
{
    map<string, methodPrt>::iterator iter;

    iter = methodNameList.find(string(methodName->valuestring));
    if (iter != methodNameList.end())
    {
        iter->second(params);
    }
}

/**
 * @brief init the ThreadUnit, create the message queue and thread
 * （初始化ThreadUnit，创建消息队列及对应的线程）
 * @param name （对应的消息队列及线程名称）
 * @param priority （对应线程的优先级）
 */
void ThreadUnit::init(string name, rt_uint8_t priority)
{
    string msgName = name + "Msg";
    string threadName = name + "Thread";

    /* 初始化消息队列 */
    int result = rt_mq_init(&message,
                            msgName.c_str(),
                            &msg_pool[0],       /* 内存池指向 msg_pool */
                            sizeof(struct msg), /* 每个消息的最大是 1024 字节 */
                            sizeof(msg_pool),   /* 内存池的大小是 msg_pool 的大小 */
                            RT_IPC_FLAG_FIFO);  /* 如果有多个线程等待，按照先来先得到的方法分配消息 */

    if (result != RT_EOK)
    {
        rt_kprintf("init message queue failed.\n");
        return;
    }

    rt_thread_t tid1 = RT_NULL;
    tid1 = rt_thread_create(threadName.c_str(), entry, &message, 1024, priority, 10);
    if (tid1 != RT_NULL)
    {
        rt_thread_startup(tid1);
    }

    rt_kprintf("UNIT:%s,Used Timer:%s\r\n", name.c_str(), TIMName.c_str());
}
